from django.shortcuts import render
from django.views import View
from django import http
from users.models import User
import json
import re, logging
from django_redis import get_redis_connection
from django.contrib.auth import login, authenticate
from django.contrib.auth import logout
from meiduo_mall1.utils.views import LoginRequiredMixin

logger = logging.getLogger('django')


# import sys
# print(sys.path)


class VerifyEmailView(View):
    '''验证邮箱'''

    def put(self, request):
        '''实现邮箱验证逻辑'''
        # 接受参数
        token = request.GET.get('token')
        # 校验参数:判断token是否为空和过期,提取user
        if not token:
            return http.JsonResponse({
                'code': 400,
                'errmsg': '缺少token'
            })
        # 调用上面封装好的方法,将token传入
        user = User.check_verify_email_token(token)
        if not user:
            return http.JsonResponse({
                'code': 400,
                'errmsg': '无效的token'
            })
        # 修改email_active的值为true
        try:
            user.email_active = True
            user.save()
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({
                'code': 400,
                'errmsg': '激活邮件失败'
            })

        # 返回邮箱验证结果
        return http.JsonResponse({
            'code': 0,
            'errmsg': 'ok'
        })


class EmailView(View):
    '''添加邮箱'''

    def put(self, request):
        '''实现添加邮箱逻辑'''
        # 接受参数
        json_dict = json.loads(request.body.decode())
        email = json_dict.get('email')

        # 校验参数
        if not email:
            return http.JsonResponse({
                'code': 400,
                'errmsg': '缺少email参数'
            })
        if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
            return http.JsonResponse({
                'code': 400,
                'errmsg': '参数email有误'
            })

        # 赋值email字段
        try:
            request.user.email = email
            request.user.save()
        except Exception as e:
            logger.error(e)
            return http.JsonResponse(
                {
                    'code': 400,
                    'errmsg': '添加邮箱失败'
                })

        return http.JsonResponse({
            'code': 0,
            'errmsg': 'ok'
        })


class UserInfoView(LoginRequiredMixin, View):
    """用户中心"""

    def get(self, request):
        # 获取界面需要的数据,进行拼接
        info_data = {
            'username': request.user.username,
            'mobile': request.user.mobile,
            'email': request.user.email,
            'email_active': request.user.email_active
        }

        return http.JsonResponse({
            'code': 0,
            'errmsg': 'ok',
            'info_data': info_data
        })


class LogoutView(View):
    '''定义退出登录接口'''

    def delete(self, request):
        '''实现退出登录的逻辑'''

        # 清理session
        logout(request)

        # 创建response对象
        response = http.JsonResponse({
            'code': 0000,
            'errmsg': 'ok'
        })

        # 调用对象的delete_cookie方法 ,清除cookie
        response.delete_cookie('username')

        # 返回响应
        return response


class LoginView(View):
    '''实现登录接口'''

    def post(self, request):

        # 1.接收参数
        dict = json.loads(request.body.decode())
        username = dict.get('username')
        password = dict.get('password')
        remembered = dict.get('remembered')

        # 2.校验整体
        if not all([username, password]):
            return http.JsonResponse({
                'code': 400,
                'errmsg': '缺少必传参数'
            })

        # 3.验证是否能够登录
        user = authenticate(username=username, password=password)

        # 判断是否为空,如果是,返回
        if user is None:
            return http.JsonResponse({
                'code': 400,
                'errmsg': '用户或者密码错误'
            })

        # 4.状态保持
        login(request, user)

        # 5. 判断是否记住用户

        if remembered != True:
            # 7.如果没有记住:关闭立即失效
            request.session.set_expiry(0)
        else:
            # 6.如果记住:设置为两周有效
            request.session.set_expiry(None)

        # 8.生成响应对象
        response = http.JsonResponse({
            'code': 0,
            'errmsg': 'ok'
        })

        # 在响应对象中设置用户名信息.
        # 将用户名写入到 cookie，有效期 14 天
        response.set_cookie('username',
                            user.username,
                            max_age=3600 * 24 * 14)

        return response


class UsernameCountView(View):
    '''判断用户名是否重复注册'''

    def get(self, request, username):
        '''判断用户名是否重复'''
        # 查询username在数据库中的个数
        try:
            count = User.objects.filter(username=username).count()

        except Exception as e:
            return http.JsonResponse({
                'code': 400,
                'errmsg': '访问数据失败'
            })
        return http.JsonResponse({
            'code': 0,
            'errmsg': 'ok',
            'count': count
        })


class MobileCountView(View):

    def get(self, request, mobile):
        '''判断手机号码是否被注册'''
        # 1.查询Mobile在mysql中的个数
        try:
            count = User.objects.filter(mobile=mobile).count()
        except Exception as e:
            return http.JsonResponse({
                'code': 400,
                'errmsg': '查询数据库出错'
            })
            # 2.返回结果(json)
        return http.JsonResponse({
            'code': 0,
            'errmsg': 'ok',
            'count': count
        })


class RegisterView(View):

    def post(self, request):
        '''接收参数,保存到数据库'''
        # 1.接收参数
        dict = json.loads(request.body.decode())
        username = dict.get('username')
        password = dict.get('password')
        password2 = dict.get('password2')
        mobile = dict.get('mobile')
        allow = dict.get('allow')
        sms_code_client = dict.get('sms_code')

        # 2.效验(整体)
        if not all([username, password, password2, mobile, allow, sms_code_client]):
            return http.JsonResponse({
                'code': 400,
                'errmsg': '缺少必传参数'
            })

        # 3.username 检验
        if not re.match(r'[a-zA-Z0-9_-]{5,20}$', username):
            return http.JsonResponse({
                'code': 400,
                'errmsg': 'username格式有误'
            })

        # 4.password检验
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return http.JsonResponse({
                'code': 400,
                'errmsg': 'password格式有误'
            })

        # 5.password2 和password
        if password != password2:
            return http.JsonResponse({'code': 400,
                                      'errmsg': '两次输入不对'})

        # 6.mobile检验
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.JsonResponse({'code': 400,
                                      'errmsg': 'mobile格式有误'})

        # 7.allow检验
        if allow != True:
            return http.JsonResponse({'code': 400,
                                      'errmsg': 'allow格式有误'})

        # 8.sms_code检验 (链接redis数据库)
        redis_conn = get_redis_connection('verify_code')

        # 9.从redis中取值
        sms_code_server = redis_conn.get('sms_%s' % mobile)

        # 10.判断该值是否存在
        if not sms_code_server:
            return http.JsonResponse({'code': 400,
                                      'errmsg': '短信验证码过期'})
        # 11.把redis中取得值和前端发的值对比
        if sms_code_client != sms_code_server.decode():
            return http.JsonResponse({'code': 400,
                                      'errmsg': '验证码有误'})

        # 12.保存到数据库 (username password mobile)
        try:
            user = User.objects.create_user(username=username,
                                            password=password,
                                            mobile=mobile)
        except Exception as e:
            return http.JsonResponse({'code': 400,
                                      'errmsg': '保存到数据库出错'})

        # 状态保持
        login(request, user)

        # 13.拼接json返回
        response = http.JsonResponse({'code': 0,
                                      'errmsg': 'ok'})

        # 在响应对象中设置用户信息
        # 将用户信息写入cookie,有效期14天
        response.set_cookie('username',
                            user.username,
                            max_age=3600 * 24 * 14)

        return response
